package com.apes.fn.crm.customComplain;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.apes.framework.api.DomainService;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.util.MapUtil;
import com.apes.fn.crm.customerExpand.FnCustomerExpand;
import com.apes.scm.masterdata.car.model.CarConfiguration;
import com.apes.scm.masterdata.car.repository.CarConfigurationRepository;
import com.apes.scm.masterdata.party.model.PartyRole;
import com.apes.scm.rbac.model.User;
import com.apes.scm.rbac.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service("fnCustomComplainService")
public class FnCustomComplainService extends DomainService {
    @Autowired
    FnCustomComplainRepository fnCustomComplainRepository;
    @Autowired
    CarConfigurationRepository carConfigurationRepository;
    @Autowired
    UserRepository userRepository;
    /***
     * 功能：创建
     * @param request
     * @return
     */
    public FnCustomComplain create(SimpleRequest request) {
        FnCustomComplain fnCustomComplain = createOrUpdateCustomerInfo(request);
        fnCustomComplain.setState("create");  //设置当前的状态
        if (!Objects.isNull(fnCustomComplain.getDept())) fnCustomComplain.setCompany(fnCustomComplain.getDept().getCompany());
        return fnCustomComplainRepository.saveAndFlush(fnCustomComplain);
    }


    /***
     * 功能： 修改
     * @param request
     * @return
     */
    public FnCustomComplain update(SimpleRequest request) {
        String id = request.get("id");
        long versions = (int) request.get("version"); // 获取当前请求的版本信息
        FnCustomComplain fnCustomComplain = fnCustomComplainRepository.findOne(id);
        if (fnCustomComplain == null) throw new RuntimeException("客诉单【" + id + "】在系统中不存在。");
        if (fnCustomComplain.getVersion() != versions) throw new RuntimeException("记录已更新或已删除，请重新提交！");  // 用于判断当前版本是否被修改
        FnCustomComplain requestCustomComplain = createOrUpdateCustomerInfo(request);
        requestCustomComplain = fnCustomComplainRepository.saveAndFlush(requestCustomComplain);
        return requestCustomComplain;
    }

    /***
     * 功能： 删除
     * @param request
     * @return
     * @throws RuntimeException
     */
    public String delete(SimpleRequest request) throws RuntimeException {
        String id = request.get("id");
        long versions = (int) request.get("version"); // 获取当前请求的版本信息
        FnCustomComplain fnCustomComplain = fnCustomComplainRepository.findOne(id);
        if (fnCustomComplain == null) throw new RuntimeException("离职申请单【" + request.get("id") + "】在系统中不存在。");
        if (fnCustomComplain.getVersion() != versions) throw new RuntimeException("记录已更新或已删除，请重新提交！");  // 用于判断当前版本是否被修改

        // 设置删除人以及状态
        FnCustomComplain requestCustomComplain = request.getO(FnCustomComplain.class);

        requestCustomComplain.setDeleteId(this.getPerson(request)); //设置人员
        requestCustomComplain.setDeleteDate(new Date()); // 设置时间
        requestCustomComplain.setState("delete");  //设置当前的状态为删除
        fnCustomComplainRepository.saveAndFlush(requestCustomComplain);

        return "删除成功！";
    }


    /***
     * 功能 转OA start 节点
     * @param request
     * @return
     * @throws RuntimeException
     */
    public FnCustomComplain transOA(SimpleRequest request) throws RuntimeException {
        //设置单据状态为处理中
        FnCustomComplain fnCustomComplain = request.getO(FnCustomComplain.class);
        // 设置转OA人
        fnCustomComplain.setInitiatOaId(this.getPerson(request)); //设置人员
        fnCustomComplain.setInitiatOaDate(new Date()); // 设置时间
        fnCustomComplain.setState("disposing");  //设置当前的状态为处理中
        fnCustomComplain.setNextDisposeSign(String.valueOf(((User) getCurrentUser(request)).getId()));  //设置客诉节点的审批人
        fnCustomComplain = fnCustomComplainRepository.save(fnCustomComplain);
        fnCustomComplainRepository.flush();
        return fnCustomComplain;
    }


    /***
     * 功能 部门处理节
     * @param request
     * @return
     * @throws RuntimeException
     */

    public FnCustomComplain transDispose(SimpleRequest request) {

        JSONObject tempJson = request.getJO();
        if (tempJson.get("nextDisposeSign") == null) throw new RuntimeException("节点候选人不能为空");
        //设置单据状态为处理中
        //获取最新的数据并设置状态
        FnCustomComplain fnCustomComplain = fnCustomComplainRepository.findOne((String) request.get("id"));
        fnCustomComplain.setState("disposing");  //设置当前的状态为处理中

        // 如果当前流程为挂起状态，执行挂起
        if (!fnCustomComplain.isActive()) {
            this.invoke("wf.suspend", MapUtil.mapper("innerBusinessType", fnCustomComplain.getInnerBusinessType(),
                    "innerBusinessKey", fnCustomComplain.getInnerBusinessKey()));
        }
        return fnCustomComplainRepository.saveAndFlush(fnCustomComplain);

    }

    public FnCustomComplain afterDispose(SimpleRequest request) {
        FnCustomComplain fnCustomComplain = fnCustomComplainRepository.findOne((String) request.get("id"));
        fnCustomComplain.setNextDisposeSign(String.valueOf(((User) this.getCurrentUser(request)).getId()));
        fnCustomComplain = fnCustomComplainRepository.save(fnCustomComplain); //设置客诉节点的审批人
        fnCustomComplainRepository.flush();
        return fnCustomComplain;
    }


    /***
     * 功能 客户回访节点
     * @param request
     * @return
     * @throws RuntimeException
     */
    public FnCustomComplain transVisit(SimpleRequest request) {
        //设置单据状态
        FnCustomComplain fnCustomComplain = fnCustomComplainRepository.findOne((String) request.get("id"));

        //设置转客服回访日期和时间
        fnCustomComplain.setTransVisitId(this.getPerson(request));
        fnCustomComplain.setTransVisitDate(new Date());
        fnCustomComplain.setState("visiting");  //设置当前的状态为回访中
        return fnCustomComplainRepository.saveAndFlush(fnCustomComplain);
    }


    /***
     * 功能 end节点
     * @param request
     * @return
     * @throws RuntimeException
     */
    public FnCustomComplain transEnd(SimpleRequest request) throws RuntimeException {

        //设置单据状态
        FnCustomComplain fnCustomComplain = fnCustomComplainRepository.findOne((String) request.get("id"));
        fnCustomComplain.setState("end");  //设置当前的状态为结单

        //设置结单人，结单日期
        fnCustomComplain.setEndId(this.getPerson(request));
        fnCustomComplain.setEndDate(new Date());

        return fnCustomComplainRepository.saveAndFlush(fnCustomComplain);
    }


    /***
     * 功能 停单申请节点
     * @param request
     * @return
     * @throws RuntimeException
     */
    public FnCustomComplain transApplyStop(SimpleRequest request) throws RuntimeException {
        //设置单据状态
        FnCustomComplain fnCustomComplain = request.getO(FnCustomComplain.class);  //设置javaBean 并格式化时间

        if (fnCustomComplain.getStartDate() == null) {
            throw new RuntimeException("启单日期不能为空");
        } else {
            if (fnCustomComplain.getStartDate().before(new Date())) {
                throw new RuntimeException("启单日期不能小于当前时间");
            }
        }

        //设置转停单日期和时间
        fnCustomComplain.setTranstopId(this.getPerson(request));
        fnCustomComplain.setTranstopDate(new Date());
        fnCustomComplain.setState("transStop");  //设置当前的状态为停单申请中

        return fnCustomComplainRepository.saveAndFlush(fnCustomComplain);
    }


    /***
     * 功能： 挂起
     * @param request
     * @return
     */
    public FnCustomComplain suspend(SimpleRequest request) {
        FnCustomComplain fnCustomComplain = request.getO(FnCustomComplain.class);  //设置javaBean 并格式化时间
        fnCustomComplain.setStopId(this.getPerson(request));
        fnCustomComplain.setStopDate(new Date());
        fnCustomComplain.setActive(false); //设置激活状态为false
        return fnCustomComplainRepository.saveAndFlush(fnCustomComplain);
    }

    /***
     * 功能： 手动启单(激活)
     * @param request
     * @return
     */
    public FnCustomComplain active(SimpleRequest request) {
        //设置单据状态
        FnCustomComplain fnCustomComplain = request.getO(FnCustomComplain.class);  //设置javaBean 并格式化时间
        fnCustomComplain.setStartId(this.getPerson(request));
        fnCustomComplain.setRealStartDate(new Date());  //设置实际启单日期
        fnCustomComplain.setActive(true);

        this.invoke("wf.activate", MapUtil.mapper("innerBusinessType", fnCustomComplain.getInnerBusinessType(),
                "innerBusinessKey", fnCustomComplain.getInnerBusinessKey()));

        return fnCustomComplainRepository.saveAndFlush(fnCustomComplain);
    }


    /***
     * 功能 分配责任人
     * @param request
     * @return
     * @throws RuntimeException
     */
    public FnCustomComplain assign(SimpleRequest request) {
        FnCustomComplain fnCustomComplain = createOrUpdateCustomerInfo(request);  //设置javaBean 并格式化时间

        //设置分配人，分配日期
        fnCustomComplain.setAssignId(this.getPerson(request)); //设置人员
        fnCustomComplain.setAssignDate(new Date()); // 设置时间
        return fnCustomComplainRepository.saveAndFlush(fnCustomComplain);
    }

    /***
     * 保存会员和车辆数据
     */
    private FnCustomComplain createOrUpdateCustomerInfo(SimpleRequest request) {
        JSONObject tempJson = request.getJO();
        FnCustomComplain customComplain = request.getO(FnCustomComplain.class);
        Object customer = "--".equals(tempJson.get("customer"))?null:tempJson.get("customer");
        Object customerCar = "".equals(tempJson.get("customerCar"))?null:tempJson.get("customerCar");

        FnCustomerExpand customerExpand = this.invoke("fn.customerExpand.updateOrInsert", MapUtil.mapper(
                "customerExpand", tempJson.get("customerExpand"),
                "customer", customer,
                "customerCar", customerCar
        ));

        customComplain.setCustomerExpand(customerExpand);
        return customComplain;
    }


    /***
     * 查询
     * 1.客户投诉数量
     * 2. 厂牌 车型
     * 3. 客户信息
     */
    public Map queryCarInfo(SimpleRequest request) {
        JSONObject tempJson = request.getJO();
        CarConfiguration carConfiguration = tempJson.containsKey("jekunModelCode") ? carConfigurationRepository.findOne(tempJson.getString("jekunModelCode")) : null;
        return MapUtil.mapper(
                "carLabel", carConfiguration != null ? carConfiguration.getCarLabel() : null,
                "carModel", carConfiguration != null ? carConfiguration.getCarModel() : null
        );
    }

    /***
     * 查询投诉数量
     */
    public Map queryCustomerInfo(SimpleRequest request) {
        JSONObject tempJson = request.getJO();
        return MapUtil.mapper(
                "complainCount", tempJson.containsKey("id") ? fnCustomComplainRepository.countCustomComplain(
                        tempJson.getString("mobile"),
                        ((PartyRole)request.getCurrentCompany()).getId()
                ) : 0
        );
    }


    /***
     * 赋能客诉单自动启单
     */
    public JSONArray restartComplainData() {
        Calendar calendar=Calendar.getInstance();
        calendar.setTime(new Date());
        int currentHour = calendar.get(Calendar.HOUR_OF_DAY);
        if( currentHour >= 18  || currentHour < 9) return new JSONArray(); //早9点到晚6点为启单日期
        List<FnCustomComplain> customComplainList = fnCustomComplainRepository.findCustomComplainRestart();

        JSONArray jsonArray = new JSONArray();
        customComplainList.stream().forEach( item ->  jsonArray.add(MapUtil.mapped(item)));
        return jsonArray;
    }

    public void restartComplainMethod(SimpleRequest request) {

        FnCustomComplain customComplain = fnCustomComplainRepository.findOne((String) request.get("id"));

        boolean isSuspend = this.invoke("wf.isProcessInstanceSuspend", MapUtil.mapper("innerBusinessType", customComplain.getInnerBusinessType(),
                "innerBusinessKey", customComplain.getInnerBusinessKey()));

        if (isSuspend) this.invoke("wf.activate", MapUtil.mapper("innerBusinessType", customComplain.getInnerBusinessType(),
                "innerBusinessKey", customComplain.getInnerBusinessKey()));

        customComplain.setStartId(userRepository.findOne(1).getPerson());
        customComplain.setRealStartDate(new Date());
        customComplain.setActive(true);
        fnCustomComplainRepository.saveAndFlush(customComplain);
    }
}
